<script setup>
import { ref, computed, onMounted, watch, reactive } from 'vue'
import { $utils } from '@jzl/utils';
import CODE_TYPE_DFT from './code-type-dft.js'
import { CodeEditor } from '@jzl/comps-mg';
import { DFT_ICONS } from '@jzl/icons';

// 定义props
const props = defineProps({
  saveMode: {
    type: String,
    default: 'save'     // save - 保存， temp - 返回json
  },
  actionMode: {
    type: String,
    default: 'ALL'      // ALL | SYNC | SCRIPT | INSERT ...
  },
  hideAction: {
    type: Boolean,
    default: false
  },
  robotId: [String, Number],
  robot: [Object],
  type: {
    type: [Number, String],
    default: 3
  },
  appId: [String, Number],
})

// 定义emits
const emit = defineEmits(['change', 'close', 'save'])

// 默认数据
let DFT = {
  name: '',
  remark: '',
  type: 3,           // '1-表单  2-流程  3-JS流程节点
  form_id: null,
  view_id: null,
  flow_id: null,
  node_id: null,
  app_id: null,
  trigger_type: "",        // 自定义
  target_type: 3,
  target_form_id: null,
  action_type: 'SCRIPT',  // INSERT / UPDATE / DELETE / UPSERT / SCRIPT
  syncmap: {},
  syncfilter: {},
  func_type: 2,
  func_id: null,
  private_func_id: null,
  func: null,
  private_func: null,
  inparams: _.get(CODE_TYPE_DFT, 'serverFuncInParam'),
  outparams: _.get(CODE_TYPE_DFT, 'serverFuncOutParam'),
  status: 1,
  script: ''
}

// 响应式数据
const form = ref(_.cloneDeep(DFT))
const origForm = ref(null)     // 原始表单/流程表单
const targetForm = ref({})     // 修改的表单
const loading = ref(false)
const error = ref(null)
const funcTab = ref('func')

// 计算属性
const isFlowForm = computed(() => {
  return origForm.value && origForm.value.use_type === 'WORKFLOW'
})

const canEditAction = computed(() => {
  return props.actionMode === 'ALL' || props.actionMode === 'SYNC'
})

const funcNameLabel = computed(() => {
  let funcType = _.get(form.value, "func_type")

  if (funcType === 1) {
    return _.get(form.value, "func.func_name")
  } else {
    return _.get(form.value, "private_func.func_name")
  }
})

const funcCodeLabel = computed(() => {
  let funcType = _.get(form.value, "func_type")

  if (funcType === 1) {
    return _.get(form.value, "func.func_code")
  } else {
    return _.get(form.value, "private_func.func_code")
  }
})

const realAppId = computed(() => {
  let appId = _.get(origForm.value, "app_id")

  if (appId && appId > 0) return appId

  appId = _.get(form.value, "app_id")

  return appId
})

// 方法定义
const errorTip = (tip) => {
  error.value = tip
  loading.value = false
}

const init = async () => {
  error.value = null
  loading.value = true
  origForm.value = null
  targetForm.value = {}

  let origFormData = null
  let targetFormData = null
  let formData = null

  // 修改
  if (props.robotId) {
    formData = await this.$japi.order.getSynctask(props.robotId)

    if (!formData) {
      return errorTip('修改数据不存在！')
    }

    // 修改反写 可操作的模式
    props.actionMode = formData.action_type === 'SCRIPT' ? 'SCRIPT' : 'SYNC'
  } else if (props.robot && props.robot.st_code) {
    formData = _.cloneDeep(props.robot)

    props.actionMode = formData.action_type === 'SCRIPT' ? 'SCRIPT' : 'SYNC'
  } else {    // 新增
    formData = _.cloneDeep(DFT)

    formData.st_code = $utils.getNanoid()
    // formData.type = props.type
    formData.form_id = props.formId
    // formData.view_id = props.viewId
    // formData.flow_id = props.flowId
    // formData.node_id = props.nodeId
    formData.app_id = props.appId
  }

  if (formData.form_id) {
    origFormData = await this.$japi.form.getFormById(formData.form_id)
  }

  if (formData.target_form_id) {
    targetFormData = await this.$japi.form.getFormById(formData.target_form_id)
    if (targetFormData) targetForm.value = targetFormData
  }

  if (!formData.inparams) {
    formData.inparams = _.get(CODE_TYPE_DFT, 'serverFuncInParam')
  }

  if (!formData.outparams) {
    formData.outparams = _.get(CODE_TYPE_DFT, 'serverFuncOutParam')
  }

  form.value = formData
  origForm.value = origFormData
  loading.value = false
}

const handleShowFormSelectWin = async () => {
  this.$WinForms({
    type: 'form',
    onSelect: async (info) => {
      let formInfo = _.get(info, 'form')

      if (!formInfo || !formInfo.form_code) return

      let formId = _.get(formInfo, 'form_id')
      let fullFormInfo = await this.$japi.form.getFormById(formId)
      targetForm.value = fullFormInfo
      form.value.target_form_id = _.get(fullFormInfo, 'form_id')
    }
  })
}

const handleShowOrigFormSelectWin = async () => {
  this.$WinForms({
    type: 'form',
    onSelect: async (info) => {
      let formInfo = _.get(info, 'form')

      if (!formInfo || !formInfo.form_code) return

      let formId = _.get(formInfo, 'form_id')
      let fullFormInfo = await this.$japi.form.getFormById(formId)
      origForm.value = fullFormInfo
      form.value.form_id = _.get(fullFormInfo, 'form_id')
    }
  })
}

const handleShowFuncParam = (tab) => {
  funcTab.value = tab
}

const handleShowCloudFuncWin = () => {
  this.$WinFuncs({
    appId: realAppId.value,
    onSelect: (func) => {
      form.value.func = func
    }
  })
}

const handleChangeFunType = () => {
  if (form.value.func_type === 2) {
    form.value.func_type = 1
  } else {
    form.value.func_type = 2
  }
}

const cancel = () => {
  emit("close")
}

const ok = async () => {
  let formData = _.cloneDeep(form.value)
  let ret = null

  if (props.saveMode === 'temp') {
    emit('save', formData)
  } else {
    loading.value = true

    if (formData.st_id) {
      ret = await this.$japi.order.updateSynctask(formData)
    } else {
      ret = await this.$japi.order.createSynctask(formData)
    }

    if (ret) {
      emit('save', formData)
    }

    loading.value = false
  }
}

// 生命周期
onMounted(() => {
  init()
})

// 监听器
watch(() => props.type, () => {
  init()
})

watch(() => props.formId, () => {
  init()
})

watch(() => props.viewId, () => {
  init()
})

watch(() => props.flowId, () => {
  init()
})

watch(() => props.nodeId, () => {
  init()
})

watch(() => props.robot, () => {
  init()
}, { deep: true })

watch(() => props.robotId, () => {
  init()
})

watch(targetForm, (val) => {
  if (val && val.form_id) {
    form.value.targetForm = _.pick(val, ['form_id', 'form_name'])
  } else {
    form.value.targetForm = val
  }
}, { deep: true })

watch(form, (val) => {
  if (loading.value) return
  emit('change', val)
}, { deep: true })
</script>

<template>
  <div class="sync-form-container" :class="{ 'error': error }" v-loading="loading" element-loading-text="">
    <div style="display: flex;border-bottom: 1px solid #F1F1F1;">
      <div class="sync-item" style="flex-flow: row;align-items: center">
        <h5 style="margin: 0px;">触发表单（商品）</h5>
        <el-tag v-if="origForm && origForm.form_name" size="medium" style="margin-right: 5px;min-width:180px;border-color:#3a8ee6;">
          {{ origForm.form_name || '' }}
        </el-tag>
        <el-button
          @click="handleShowOrigFormSelectWin"
          size="small"
          class="fixed-width"
          type="primary"
          plain
          :disabled="isView"
        >选择表单</el-button>

        <template v-if="canEditAction">
          <h5 style="margin: 0px 10px 0px 30px;">执行动作</h5>
          <el-radio-group
            v-model="form.action_type"
            size="small"
          >
            <el-radio-button label="SCRIPT">低码操作</el-radio-button>
          </el-radio-group>
        </template>
      </div>
    </div>
    <div class="sync-form">
      <template v-if="form.action_type === 'SCRIPT'">
        <div class="lc-func-def">
          <div
            @click="handleShowFuncParam('in')"
            class="lc-func-node cicle"
            :class="{ 'active': funcTab === 'in' }"
          >
            入参设置
          </div>

          <div
            @click="handleShowFuncParam('func')"
            class="lc-func-node lc-func-info"
            :class="{ 'active': funcTab === 'func' }"
          >
            <div class="tag tag-type">
              <JIcon
                :icon="DFT_ICONS.cloud"
                v-if="form.func_type === 1"
              />
              <JIcon
                :icon="DFT_ICONS.codepen"
                v-else
              />
              {{ form.func_type === 1 ? '云函数' : '专属函数' }}
              <div
                class="tag tag-change"
                v-tippy
                content="点击切换 云函数/定制函数"
                @click="handleChangeFunType"
              >
                <JIcon
                  :icon="DFT_ICONS.exchange"
                />
              </div>
            </div>
            <div class="func-win-btn" @click="handleShowCloudFuncWin" v-if="form.func_type === 1">选择云函数</div>
            <div class="info">
              <div class="func-name func-code" v-if="funcCodeLabel" v-text="funcCodeLabel"></div>
              <div class="func-name" v-if="funcNameLabel" v-text="funcNameLabel"></div>
              <template v-if="!funcNameLabel && !funcCodeLabel">请选择/创建函数</template>
            </div>
          </div>

          <div @click="handleShowFuncParam('out')" class="lc-func-node cicle last" :class="{ 'active': funcTab === 'out' }">
            结果设置
          </div>
        </div>
        <div class="svc-target lc-code-wrap">
          <template v-if="funcTab === 'func'">
            <lownode-func
              v-if="form.func_type === 1"
              v-model="form.func"
              key="cloud"
              :is-view="true"
            />
            <lownode-func
              v-else
              v-model="form.private_func"
              key="private"
            />
          </template>
          <CodeEditor
            v-if="funcTab === 'in'"
            v-model="form.inparams"
          />
          <CodeEditor
            v-if="funcTab === 'out'"
            v-model="form.outparams"
          />
        </div>
      </template>
      <div v-else-if="!loading" class="svc-target">
        <template v-if="form.action_type !== 'SCRIPT'">
          <div class="sync-item">
            <h5>修改目标</h5>
            <div style="display: flex;align-items: center;">
              <el-radio-group v-model="form.target_type" size="small">
                <el-radio-button :label="1">当前数据</el-radio-button>
                <el-radio-button :label="2">当前表单</el-radio-button>
                <el-radio-button :label="3">自定义表单</el-radio-button>
              </el-radio-group>
            </div>
          </div>
          <div class="sync-item" v-if="form.target_type === 3">
            <h5>目标表单</h5>
            <div style="display: flex;align-items: center;">
              <el-tag v-if="targetForm && targetForm.form_name"
                      size="medium" style="margin-right: 5px;min-width:180px;border-color:#3a8ee6;">
                {{ targetForm.form_name || '' }}
              </el-tag>
              <el-button @click="handleShowFormSelectWin" size="mini" class="fixed-width"
                         icon="el-icon-tickets"
                         type="primary" plain :disabled="isView">选择表单</el-button>
            </div>
          </div>
        </template>
        <div class="sync-item" v-if="(form.action_type === 'UPDATE' || form.action_type === 'UPSERT' || form.action_type === 'DELETE') && form.target_type != 1">
          <h5>数据同步条件
            <p class="sync-hd">修改目标表单中满足以下条件的数据（必须添加）</p>
          </h5>
          <div class="table-container">
            <rules v-model="form.syncfilter" type="data" :input-form-id="targetForm && targetForm.form_id"
                   :rela-form-id="origForm && origForm.form_id" :force-enable="true"></rules>
          </div>
        </div>
        <div class="sync-item" v-if="form.action_type === 'UPDATE' || form.action_type === 'UPSERT' || form.action_type === 'INSERT'">
          <h5>数据同步设置
            <p v-if="form.action_type === 'UPDATE'" class="sync-hd">对满足条件的数据，按以下规则修改</p>
            <p v-else-if="form.action_type === 'UPSERT'" class="sync-hd">对满足条件的数据，按以下规则修改/创建</p>
            <p v-else class="sync-hd">按以下规则创建</p>
          </h5>
          <div class="table-container">
            <mapping-rules v-model="form.syncmap" :target-form-id="targetForm && targetForm.form_id"
                           :rela-form-id="origForm && origForm.form_id"></mapping-rules>
          </div>
        </div>
      </div>

      <div class="error-tip-txt" v-text="error"></div>
    </div>
    <div class="demo-drawer__footer clear" v-if="!hideAction">
      <el-button type="primary" @click="ok()">确 定</el-button>
      <el-button @click="cancel()">取 消</el-button>
    </div>
  </div>
</template>
